using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Comteck.Dto.Orders;
using Comteck.Ktt.Services.Orders;
using Comteck.Ktt.WinUI.Goods;
using Comteck.Localization;
using Comteck.Winforms;
using Comteck.Winforms.Dialog;
using Comteck.Winforms.Forms;
using Comteck.Winforms.Infrastructure;
using DevExpress.XtraBars;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Views.Grid;
using ExpressMapper.Extensions;
using Microsoft.Extensions.DependencyInjection;

namespace Comteck.Ktt.WinUI.Orders {
  /// <summary>
  /// 
  /// </summary>
  public partial class FrmSaleOrderAdmin : FrmBase {

    #region fields

    private readonly ISaleOrderService saleOrderService;
    private List<int> selfOrgIdList;

    #endregion

    #region ctor

    /// <summary>
    /// 
    /// </summary>
    /// <param name="saleOrderService"></param>
    public FrmSaleOrderAdmin(ISaleOrderService saleOrderService) {
      this.saleOrderService = saleOrderService;
      InitializeComponent();
    }

    #endregion

    #region form load

    /// <summary>
    /// form load
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void FrmSaleOrderAdmin_Load(object sender, EventArgs e) {
      if (this.DesignMode) {
        return;
      }

      ucSaleOrder1.SetAjaxLoadHelper(ajaxLoad);

      // page
      ucSaleOrder1.ucDataNavigator1.UcDataNavigatorPaged += () => {
        btnSearch.PerformClick();
      };

     ucSaleOrder1.gvMain.DoubleClick += (sender1, e1) => {
         ucSaleOrder1.gvMain.OptionsBehavior.Editable = true;
     };



      BindHelper.BindWithArray<EnumSaleOrderStatus>(searchStatus, null, EnumSaleOrderStatusList.ManageView.ToArray());
      searchStatus.CheckAll();
    }

    #endregion

    #region search

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnSearch_ItemClick(object sender, ItemClickEventArgs e) {
      // search model
      var searchModel = new SaleOrderQuery() {
        Search_Date_Type = 1,
        Search_Begin_Date = searchDateRange.BeginDate,
        Search_End_Date = searchDateRange.EndDate,
        StatusList = searchStatus.GetCheckedValues<int>().ToList(),
        SelfOrgIdList = selfOrgIdList,
        Code = searchCode.EditValue.To<string>(),
        GroupNumber = searchGroupNumber.EditValue.To<string>(),
        DeliveryCode = searchDeliveryCode.EditValue.To<string>(),
        Page = 1,
      };
      await ucSaleOrder1.SearchDataAsync(searchModel);
    }

    private void searchCode_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Enter) {
        btnSearch.PerformClick();
      }
    }

    private void searchGroupNumber_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Enter) {
        btnSearch.PerformClick();
      }
    }

    private void searchDeliveryCode_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Enter) {
        btnSearch.PerformClick();
      }
    }

    private void searchSelfOrgId_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Enter) {
        btnSearch.PerformClick();
      }
    }

    #endregion

    #region 自提点

    private void searchSelfOrgId_Properties_ButtonClick(object sender, ButtonPressedEventArgs e) {
      switch (e.Button.Tag) {
        case 1: {
            // 选择提货点
            var form = SysGlobal.ServiceProvider.GetRequiredService<FrmSelfOrgDialog>();
            form.SelectType = EnumSelectType.Multi;
            form.ImportAction = (list) => {
              if (list.IsNullOrEmpty()) {
                return false;
              }

              selfOrgIdList = list.Select(x => x.Id).ToList();
              searchSelfOrgId.EditValue = string.Join(",", list.Select(x => x.Name));
              return true;
            };
            form.Owner = this;
            form.ShowDialog();
          }
          break;
        case 2: {
            // 清楚数据
            selfOrgIdList = null;
            searchSelfOrgId.EditValue = null;
          }
          break;
        default:
          break;
      }
    }

    #endregion

    #region 导入

    private void btnImport_ItemClick(object sender, ItemClickEventArgs e) {
      var form = new FrmExcelImportDialog() {
        TemplateType = Winforms.Templates.EnumTemplateType.SaleOrder,
        CheckTemplateColumnsCount = false,
      };

      form.OnChangeExcelDataAsync += this.Form_OnChangeExcelDataAsync;
      form.OnSaveExcelDataAsync += this.Form_OnSaveExcelDataAsync;

      // 导入成功后查询数据
      if (form.ShowDialog() == DialogResult.Yes) {
        btnSearch.PerformClick();
      }
    }

    /// <summary>
    /// 改变数据源结构
    /// </summary>
    /// <param name="table"></param>
    /// <param name="gridView"></param>
    /// <returns></returns>
    private async Task<object> Form_OnChangeExcelDataAsync(DataTable table, GridView gridView) {
      ajaxLoad?.Show();
      var result = await saleOrderService.ChangeExcelDataAsync(table);
      ajaxLoad?.Hide();
      return result;
    }

    /// <summary>
    /// 保存excel的数据
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    private async Task<bool> Form_OnSaveExcelDataAsync(object data, GridView gridView) {
      var list = data as List<SaleOrderExcelDto>;
      list = list.Where(x => x.IsValid).ToList();

      // 先校验自提点标签未维护的记录
      var selfOrgTagNotExists = list.Where(x => !x.SelfOrgTagIdExists).ToList();
      if (selfOrgTagNotExists.IsNotNullOrEmpty()) {
        var form = SysGlobal.ServiceProvider.GetRequiredService<FrmSelfOrgBatchAction>();
        form.IdList = selfOrgTagNotExists.Select(x => x.SelfOrgId).Distinct().ToList();
        form.Owner = this;
        form.ShowDialog();
      }

      // 在校验商品重量没有维护的记录
      var productWeightNotExists = list.SelectMany(x => x.DetailList).Where(x => x.Weight <= decimal.Zero).ToList();
      if (productWeightNotExists.IsNotNullOrEmpty()) {
        var form = SysGlobal.ServiceProvider.GetRequiredService<FrmProductBatchAction>();
        form.IdList = productWeightNotExists.Select(x => x.ProductId).Distinct().ToList();
        form.Owner = this;

        // 保存成功，刷新重量
        if (form.ShowDialog() == DialogResult.Yes) {
          list = await saleOrderService.FillProductInfoForExcelDataAsync(list);
        }
      }

      // 保存订单数据
      ajaxLoad?.Show();
      try {
        await saleOrderService.SaveExcelDataAsync(list);
        ajaxLoad?.Hide();
        this.Invoke(new Action(() => {
          this.ShowMsg(BaseResources.Import_Success);
        }));
        return true;
      } catch (Exception ex) {
        ajaxLoad?.Hide();
        this.Invoke(new Action(() => {
          this.ShowMsg(BaseResources.Import_Failed, ex.Message);
        }));

        return false;
      }
    }

    #endregion

    #region 放入回收站

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnRecycle_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.RecycleDataAsync();
    }

    #endregion

    #region 拆单

    /// <summary>
    /// 将多个商品拆分到新订单上
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnSplitGoods2NewOrderAsync_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.SplitGoods2NewOrderAsync();
    }

    /// <summary>
    /// 将一个商品分解成多个订单
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnSplitOrder_ItemClick(object sender, ItemClickEventArgs e) {
      ucSaleOrder1.SplitOrder(this);
    }

    #endregion

    #region 取消拆单

    /// <summary>
    /// 取消拆单
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnCombineOrder_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.CombineOrderAsync();
    }

    #endregion

    #region 审核/反审核

    private async void btnAudit_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.AuditAsync();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnAuditForce_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.AuditForceAsync();
    }

    #endregion

    #region 获取运单号

    /// <summary>
    /// 获取运单号
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnGetDeliveryCode_ItemClick(object sender, ItemClickEventArgs e) {
      // 查询选中的记录
      var rows = ucSaleOrder1.gvMain.GetSelectedRowsList<SaleOrderDto>();
      if (rows.IsNullOrEmpty()) {
        return;
      }

      if (rows.Any(x => x.Status == (int) EnumSaleOrderStatus.未审核)) {
        this.ShowMsg("请先将未审核的订单审核");
        return;
      }

      // confirm
      if (this.ShowMsg(BaseResources.Execute_Confirm, null,MessageBoxButtons.YesNo, MessageBoxIcon.Question,
        MessageBoxDefaultButton.Button1) == DialogResult.No) {
        return;
      }

      ajaxLoad.Show();
      var index = 0;
      this.ShowWaitForm("开始获取运单号，请等待");
      foreach (var row in rows) {
        this.ShowWaitForm($"共需获取【{rows.Count}】个运单号，已经获取了【{index}】个\n当前正在获取订单【{row.Code}】");

        // 已有运单号
        if (row.DeliveryCode.IsNotNullOrEmpty()) {
          continue;
        }

        // 获取
        var result = await saleOrderService.GetWaybillNoAsync(row.Id);
        if (result.Code == 1) {
          result.Data.MapTo(row);
        } else {
          if (index == 0) {
            this.CloseWaitForm(3000, $"获取失败：{result.Message}");
          } else {
            this.CloseWaitForm(3000, $"获取中断：{result.Message}，已成功获取{index}个运单号");
          }
          ajaxLoad.Hide();
          ucSaleOrder1.gvMain.RefreshData();
          return;
        }

        index++;
      }
      this.CloseWaitForm(2000, "运单号获取完成");
      ajaxLoad.Hide();
      ucSaleOrder1.gvMain.RefreshData();
    }

    #endregion

    #region 获取运单状态

    /// <summary>
    /// 获取运单状态
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnGetDeliveryCodeStatus_ItemClick(object sender, ItemClickEventArgs e) {
      // 查询选中的记录
      var rows = ucSaleOrder1.gvMain.GetSelectedRowsList<SaleOrderDto>().Where(x => x.DeliveryCode.IsNotNullOrEmpty()).ToList();
      if (rows.IsNullOrEmpty()) {
        return;
      }

      // confirm
      if (this.ShowMsg(BaseResources.Execute_Confirm, null, MessageBoxButtons.YesNo, MessageBoxIcon.Question,
        MessageBoxDefaultButton.Button1) == DialogResult.No) {
        return;
      }

      ajaxLoad.Show();
      var index = 0;
      this.ShowWaitForm("开始查询投递状态，请等待");
      foreach (var row in rows) {
        this.ShowWaitForm($"共需查询【{rows.Count}】个运单号，已经查询了【{index}】个\n当前正在查询订单【{row.Code}】");

        // 已有运单号
        if (row.DeliveryCode.IsNullOrEmpty()) {
          continue;
        }

        // 获取
        var result = await saleOrderService.GetWaybillNoPathAsync(row.Id);
        if (result.Code == 1) {
          result.Data.MapTo(row);
        } else {
          if (index == 0) {
            this.CloseWaitForm(3000, $"查询失败：{result.Message}");
          } else {
            this.CloseWaitForm(3000, $"查询中断：{result.Message}，已成功查询{index}个运单号");
          }
          ajaxLoad.Hide();
          this.RefreshGridAfterDeliveryStatus();
          return;
        }

        index++;
      }
      this.CloseWaitForm(2000, "投递状态查询完成");
      ajaxLoad.Hide();
      this.RefreshGridAfterDeliveryStatus();
    }

    /// <summary>
    /// 
    /// </summary>
    private void RefreshGridAfterDeliveryStatus() {
      ucSaleOrder1.gvMain.BeginUpdate();
      ucSaleOrder1.gvMain.RefreshData();
      ucSaleOrder1.gvMain.BestFitColumns();
      ucSaleOrder1.gvMain.EndUpdate();
      ucSaleOrder1.gvMain_FocusedRowObjectChanged(null, null);
    }

    #endregion

    #region 取消运单号

    /// <summary>
    /// 取消运单号
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnCancelDeliveryCode_ItemClick(object sender, ItemClickEventArgs e) {
      // 查询选中的记录
      var rows = ucSaleOrder1.gvMain.GetSelectedRowsList<SaleOrderDto>();
      if (rows.IsNullOrEmpty()) {
        return;
      }

      // confirm
      if (this.ShowMsg(BaseResources.Execute_Confirm, null, MessageBoxButtons.YesNo, MessageBoxIcon.Question,
        MessageBoxDefaultButton.Button1) == DialogResult.No) {
        return;
      }

      // 添加备注
      var frm = new FrmDescriptionDialog {
        Text = "运单号取消原因"
      };
      frm.ShowDialog();
      if (frm.DialogResult == DialogResult.No) {
        return;
      }

      ajaxLoad.Show();
      var index = 0;
      this.ShowWaitForm("开始取消运单号，请等待");
      foreach (var row in rows) {
        this.ShowWaitForm($"共需取消【{rows.Count}】个运单号，已经取消了【{index}】个\n当前正在取消订单【{row.Code}】");

        // 已有运单号
        if (row.DeliveryCode.IsNullOrEmpty()) {
          continue;
        }

        // 获取
        var result = await saleOrderService.CancelWaybillNoAsync(row.Id, frm.Description);
        if (result.Code == 1) {
          result.Data.MapTo(row);
        } else {
          if (index == 0) {
            this.CloseWaitForm(3000, $"取消失败：{result.Message}");
          } else {
            this.CloseWaitForm(3000, $"取消中断：{result.Message}，已成功取消{index}个运单号");
          }
          ajaxLoad.Hide();
          ucSaleOrder1.gvMain.RefreshData();
          return;
        }

        index++;
      }
      this.CloseWaitForm(2000, "运单号取消完成");
      ajaxLoad.Hide();
      ucSaleOrder1.gvMain.RefreshData();
    }

    #endregion

    #region 打印

    /// <summary>
    /// print
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnPrint_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.PrintAsync(this.MenuAuth?.Id);
    }

    #endregion

    #region 反打印

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnUnPrint_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.UnPrintAsync();
    }

    #endregion

    #region 批量反打印

    private async void btnUnAudit_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.UnAuditAsync();
    }

    #endregion

    #region 重刷商品重量

    /// <summary>
    /// 重刷商品重量
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnRefreshWeight_ItemClick(object sender, ItemClickEventArgs e) {
      await ucSaleOrder1.RefreshWeightAsync();
    }

    #endregion

    #region export

    /// <summary>
    /// export
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnExport_ItemClick(object sender, ItemClickEventArgs e) {
      ucSaleOrder1.ExportDialog();
    }

    #endregion

    #region 合并订单

    /// <summary>
    /// 合并订单
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void btnMergeOrders_ItemClick(object sender, ItemClickEventArgs e) {
      try {
        ajaxLoad?.Show();
        
        // 查找可合并的订单
        var mergeableOrders = await saleOrderService.FindMergeableOrdersAsync();
        
        ajaxLoad?.Hide();
        
        if (mergeableOrders == null || mergeableOrders.Count == 0) {
          this.ShowMsg("没有找到可合并的订单（收件地址、手机号、自提点相同的未审核订单）");
          return;
        }
        
        // 显示合并确认对话框
        using (var dialog = new FrmMergeOrdersDialog()) {
          dialog.OrderList = mergeableOrders;
          
          if (dialog.ShowDialog() == DialogResult.OK && dialog.SelectedOrderIds != null && dialog.SelectedOrderIds.Count > 1) {
            ajaxLoad?.Show();
            
            try {
              // 按分组进行合并
              var selectedOrders = mergeableOrders.Where(o => dialog.SelectedOrderIds.Contains(o.Id)).ToList();
              var groups = selectedOrders.GroupBy(o => new {
                RecipientAddress = o.RecipientAddress?.Trim(),
                RecipientPhone = o.RecipientPhone?.Trim(),
                SelfOrgId = o.SelfOrgId
              }).ToList();
              
              var successCount = 0;
              var errorMessages = new List<string>();
              
              foreach (var group in groups) {
                var groupOrderIds = group.Select(o => o.Id).ToList();
                if (groupOrderIds.Count >= 2) {
                  var result = await saleOrderService.MergeOrdersAsync(groupOrderIds);
                  if (result.Code == 1) {
                    successCount++;
                  } else {
                    errorMessages.Add($"分组[{group.Key.RecipientAddress}]: {result.Message}");
                  }
                }
              }
              
              ajaxLoad?.Hide();
              
              if (successCount > 0) {
                this.ShowMsg($"成功合并了 {successCount} 个分组的订单");
                btnSearch.PerformClick(); // 刷新数据
              }
              
              if (errorMessages.Count > 0) {
                this.ShowMsg($"部分合并失败：\n{string.Join("\n", errorMessages)}");
              }
              
            } catch (Exception ex) {
              ajaxLoad?.Hide();
              this.ShowMsg($"合并订单失败：{ex.Message}");
            }
          }
        }
        
      } catch (Exception ex) {
        ajaxLoad?.Hide();
        this.ShowMsg($"查找可合并订单失败：{ex.Message}");
      }
    }

    #endregion

    #region close

    /// <summary>
    /// close
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnClose_ItemClick(object sender, ItemClickEventArgs e) {
      this.Close();
    }

    #endregion
  }
}
